/*
 * FixedSizeRecordSerializer.h
 *
 *  Created on: Nov 26, 2012
 *      Author: m
 */

#ifndef FIXEDSIZERECORDSERIALIZER_H_
#define FIXEDSIZERECORDSERIALIZER_H_

#include "Serializer.h"

namespace physical
{

/**
 * Serializador de elementos de tamaño fijo
 *
 * @warning Tener en cuenta que para que un elemento
 *  sea considerado de tamaño fijo tiene que ser un
 *  tipo básico o una estructura con el atributo
 *  __packed__, sino puede haber problemas de
 *  alineamiento al serializar.
 *
 *  Por ejemplo:
 *
 *  struct __attribute__ ((__packed__)) Registro
 *  {
 *      // ...
 *  }
 */
template< typename T >
class FixedSizeRecordSerializer: public physical::Serializer<T>
{
public:

    /**
     * Constructor por Defecto
     */
    FixedSizeRecordSerializer()
    {
    }

    /**
     * Destructor
     */
    virtual ~FixedSizeRecordSerializer()
    {
    }

    /**
     * Serializa un elemento de tamaño fijo
     *
     * @param element Elemento a serializar
     * @param block Array de bytes en donde se serializa el elemento
     * @return Cantidad de bytes escritos en el block
     */
    size_t serialize( const T& element, byteStream block )
    {
        memcpy( block, &element, sizeof(T) );

        return sizeof(T);
    }

    /**
     * Deserializa un elemento de tamaño fijo
     *
     * @param block Array de bytes donde está serializado el elemento
     * @param element Referencia al elemento deserializado
     * @return Cantidad de bytes utilizados de block para deserializar
     */
    size_t deserialize( const byteStream block, T& element )
    {
        memcpy( &element ,block, sizeof(T) );

        return sizeof(T);
    }

    /**
     * Devuelve la cantidad de bytes que ocupa el elemento al ser serializado
     *
     * @param element Elemento a probar
     * @return Cantidad de bytes que ocuparía el elemento serializado
     */
    size_t getSize( const T& element )
    {
        return sizeof(T);
    }
};

} /* namespace physical */
#endif /* FIXEDSIZERECORDSERIALIZER_H_ */
